From: Keir Fraser Date: Tue, 2 Oct 2007 09:46:23 +0000 (+0100) Subject: Add XENPF_getidletime. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14929^2~5 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=faac4d5f0c787e9baeb9dc36c38e6cf700cada47;p=xen.git Add XENPF_getidletime. Signed-off-by: Rik van Riel Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 86180d1a73..286c362324 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -36,6 +36,8 @@ DEFINE_SPINLOCK(xenpf_lock); # define copy_from_compat copy_from_guest # undef copy_to_compat # define copy_to_compat copy_to_guest +# undef guest_from_compat_handle +# define guest_from_compat_handle(x,y) ((x)=(y)) #else extern spinlock_t xenpf_lock; #endif @@ -142,21 +144,14 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) case XENPF_microcode_update: { extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len); -#ifdef COMPAT XEN_GUEST_HANDLE(void) data; -#endif ret = xsm_microcode(); if ( ret ) break; -#ifndef COMPAT - ret = microcode_update(op->u.microcode.data, - op->u.microcode.length); -#else guest_from_compat_handle(data, op->u.microcode.data); ret = microcode_update(data, op->u.microcode.length); -#endif } break; @@ -286,6 +281,9 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) break; case XENPF_change_freq: + ret = -ENOSYS; + if ( cpufreq_controller != FREQCTL_dom0_kernel ) + break; ret = -EINVAL; if ( op->u.change_freq.flags != 0 ) break; @@ -294,11 +292,46 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) &op->u.change_freq.freq); break; + case XENPF_getidletime: + { + uint32_t i, nr_cpus; + uint64_t idletime; + struct vcpu *v; + XEN_GUEST_HANDLE(uint64_t) idletimes; + + ret = -ENOSYS; + if ( cpufreq_controller != FREQCTL_dom0_kernel ) + break; + + guest_from_compat_handle(idletimes, op->u.getidletime.idletime); + nr_cpus = min_t(uint32_t, op->u.getidletime.max_cpus, NR_CPUS); + + for ( i = 0; i < nr_cpus; i++ ) + { + /* Assume no holes in idle-vcpu map. */ + if ( (v = idle_vcpu[i]) == NULL ) + break; + + idletime = v->runstate.time[RUNSTATE_running]; + if ( v->is_running ) + idletime += NOW() - v->runstate.state_entry_time; + + ret = -EFAULT; + if ( copy_to_guest_offset(idletimes, i, &idletime, 1) ) + goto out; + } + + op->u.getidletime.nr_cpus = i; + ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0; + } + break; + default: ret = -ENOSYS; break; } + out: spin_unlock(&xenpf_lock); return ret; diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h index ad7847a9d9..16bf686d4a 100644 --- a/xen/include/public/platform.h +++ b/xen/include/public/platform.h @@ -164,7 +164,7 @@ struct xenpf_enter_acpi_sleep { typedef struct xenpf_enter_acpi_sleep xenpf_enter_acpi_sleep_t; DEFINE_XEN_GUEST_HANDLE(xenpf_enter_acpi_sleep_t); -#define XENPF_change_freq 52 +#define XENPF_change_freq 52 struct xenpf_change_freq { /* IN variables */ uint32_t flags; /* Must be zero. */ @@ -174,6 +174,17 @@ struct xenpf_change_freq { typedef struct xenpf_change_freq xenpf_change_freq_t; DEFINE_XEN_GUEST_HANDLE(xenpf_change_freq_t); +#define XENPF_getidletime 53 +struct xenpf_getidletime { + /* IN variables. */ + uint32_t max_cpus; + XEN_GUEST_HANDLE(uint64_t) idletime; + /* OUT variables. */ + uint32_t nr_cpus; +}; +typedef struct xenpf_getidletime xenpf_getidletime_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_getidletime_t); + struct xen_platform_op { uint32_t cmd; uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ @@ -187,6 +198,7 @@ struct xen_platform_op { struct xenpf_firmware_info firmware_info; struct xenpf_enter_acpi_sleep enter_acpi_sleep; struct xenpf_change_freq change_freq; + struct xenpf_getidletime getidletime; uint8_t pad[128]; } u; };